﻿#include "wordopcontrolledoperation.h"
#include  "device.h"

WordopControlLEDOperation::WordopControlLEDOperation(QObject *parent)
    : Operation{parent}
    , m_nChannel(0)
    , m_nValue(100)
    , m_pDescription((Description*)parent)
{

}

Operation* WordopControlLEDOperation::clone(Operation* pOperation){
    Operation::clone(pOperation);

    m_nChannel = ((WordopControlLEDOperation*)pOperation)->GetChannel();
    m_nValue = ((WordopControlLEDOperation*)pOperation)->GetLEDValue();
    m_pDescription = ((WordopControlLEDOperation*)pOperation)->GetDescription();
    return this;
}

int WordopControlLEDOperation::nChannel() const
{
    return m_nChannel;
}

void WordopControlLEDOperation::setNChannel(int newNChannel)
{
    m_nChannel = newNChannel;
}

int WordopControlLEDOperation::nValue() const
{
    return m_nValue;
}

void WordopControlLEDOperation::setNValue(int newNValue)
{
    m_nValue = newNValue;
}

void WordopControlLEDOperation::PrepareCMD(){
    m_nWordopCMD.identifier = 0x40;
    m_nWordopCMD.len = 0x05;
    m_nWordopCMD.code = 0x01;
    m_nWordopCMD.id = 0x00;
    m_nWordopCMD.wordopSubCmd.cmd = 0x1A;
    m_nWordopCMD.wordopSubCmd.channel = m_nChannel;
    m_nWordopCMD.wordopSubCmd.data = m_nValue;
    m_nWordopCMD.pWordopSubCmds = NULL;
    ChkSum(m_nWordopCMD);
}

void WordopControlLEDOperation::ChkSum(WORDOPCMD& wordopcmd){
    int len;
    // 计算长度
    if(wordopcmd.pWordopSubCmds == NULL){
        len = 2 + sizeof(wordopcmd.wordopSubCmd);
    }else{
        len = 2 + sizeof(wordopcmd.wordopSubCmd)
              + sizeof(wordopcmd.pWordopSubCmds);
    }
    wordopcmd.len = len;
    // 计算校验和
    unsigned int sum = 0;
    sum += (wordopcmd.identifier + wordopcmd.len + wordopcmd.code + wordopcmd.id
            + wordopcmd.wordopSubCmd.cmd
            + wordopcmd.wordopSubCmd.channel
            + wordopcmd.wordopSubCmd.data);

    if(wordopcmd.pWordopSubCmds != NULL){
        int count = sizeof(wordopcmd.pWordopSubCmds) / sizeof(WORDOPSUBCMD);
        for(int i = 0;i < count;i++){
            sum += wordopcmd.pWordopSubCmds[i].cmd;
            sum += wordopcmd.pWordopSubCmds[i].channel;
            sum += wordopcmd.pWordopSubCmds[i].data;
        }
    }

    wordopcmd.chksum = (unsigned char)(sum & 0x000000FF);
}

QByteArray  WordopControlLEDOperation::ConvertCMD2Bytes(WORDOPCMD& wordopcmd){
    QByteArray bytes;
    bytes.append(wordopcmd.identifier);
    bytes.append(wordopcmd.len);
    bytes.append(wordopcmd.code);
    bytes.append(wordopcmd.id);
    bytes.append(wordopcmd.wordopSubCmd.cmd);
    bytes.append(wordopcmd.wordopSubCmd.channel);
    bytes.append(wordopcmd.wordopSubCmd.data);
    if(wordopcmd.pWordopSubCmds != NULL){
        int count = sizeof(wordopcmd.pWordopSubCmds) / sizeof(WORDOPSUBCMD);
        for(int i = 0;i < count;i++){
            bytes.append(wordopcmd.pWordopSubCmds[i].cmd);
            bytes.append(wordopcmd.pWordopSubCmds[i].channel);
            bytes.append(wordopcmd.pWordopSubCmds[i].data);
        }
    }
    bytes.append(wordopcmd.chksum);
    return bytes;
}

void WordopControlLEDOperation::run(){
    qDebug() << "ControlLED is Running!";
    qDebug() << QString("channel = %1,value = %2").arg(m_nChannel).arg(m_nValue);

    Device* pDevice = m_pDescription->FindDeviceById(m_strDeviceID);
    QString message = QString("ControlLED : channel = %1 and value = %2.").arg(m_nChannel).arg(m_nValue);
    PrepareCMD();
    QByteArray bytes = ConvertCMD2Bytes(m_nWordopCMD);
    pDevice->writeData(QVariant(bytes));
    //pDevice->writeData(message.toLatin1());
    qDebug() << "WordopControlLEDOperation finished!";
}

QString WordopControlLEDOperation::getClassName(){
    return this->metaObject()->className();
}

void WordopControlLEDOperation::writeXML(QXmlStreamWriter& writer){
    // 写入当前操作的信息
    writer.writeStartElement("WordopControlLEDOperation");
    writer.writeAttribute("device", m_strDeviceID);
    writer.writeTextElement("channel", QString::number(m_nChannel));
    writer.writeTextElement("value", QString::number(m_nValue));
    writer.writeEndElement();  // 结束当前操作的元素
}

void WordopControlLEDOperation::readFromXML(QXmlStreamReader& reader){
    QXmlStreamAttributes attributes = reader.attributes();
    if(attributes.hasAttribute("device")) {
        m_strDeviceID = attributes.value("device").toString();
    }

    QXmlStreamReader::TokenType token = reader.readNext();
    while (!(reader.tokenType() == QXmlStreamReader::EndElement &&
             reader.name() == QStringLiteral("WordopControlLEDOperation"))) {

        if (reader.name() == QStringLiteral("channel")) {
            m_nChannel = reader.readElementText().toInt();
        }else if (reader.name() == QStringLiteral("value")) {
            m_nValue = reader.readElementText().toInt();
        }

        reader.readNext();
    }
}
